Lib与Dll之间的关系

您所在的位置:网站首页 dll 和lib Lib与Dll之间的关系

Lib与Dll之间的关系

2024-07-15 16:50| 来源: 网络整理| 查看: 265

如图所示

 

LIB分为两种库:

一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。

一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。

 

动态链接共有两种链接方式:

动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。

静态链接使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。

 

动态链接分为两种:

隐式链接:需要头文件.h、.lib文件才能编译,需要.dll文件才能运行,我们用的最多的就是这种隐式链接;

显式链接:使用LoadLibrary、GetProcAddress装载,需要dll即可。

 

LoadLibrary函数利用一个DLL的名称作为参数,返回DLL的实例(HINSTANCE类型是实例的句柄),通常调用该函数后需要查看一下函数返回是否成功,如果不成功则这个实例的值就是NULL(句柄无效),判断此值是不是null,如果是,此时调用函数FreeLibrary释放DLL获得的内存。

GetProcAddress函数利用DLL的句柄和函数的名称作为参数,返回相应的函数指针,同时必须使用强转;判断函数指针是否为NULL,如果是则调用函数FreeLibrary释放DLL获得的内存。此后,可以使用函数指针来调用实际的函数。

最后要记得使用FreeLibrary函数释放内存。

 

 

使用LoadLibrary显式链接,那么在函数的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:

(0)lib与dll中导出时,lib记录的dll地址

(1)包含EXE文件的目录

(2)工程目录

(3)Windows系统目录

(4)Windows目录

(5)列在Path环境变量中的一系列目录

 

.h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的。

附加依赖项的是.lib不是.dll,若生成了DLL,则肯定也生成 LIB文件。如果要完成源代码的编译和链接,有头文件和lib就够了。如果也使动态连接的程序运行起来,有dll就够了。在开发和调试阶段,当然最好都有。

 

.h .lib .dll三者的关系是:

H文件作用是: 声明函数接口 

DLL文件作用是: 函数可执行代码 

LIB文件的作用: 当我们在自己的程序中引用了一个H文件里的函数,编链器怎么知道该调用哪个DLL文件呢?这就是LIB文件的作用: 告诉链接器 调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置 ,这也就是为什么需要附加依赖项 .LIB文件,它起到桥梁的作用。

 

静态库和共享库都是一个obj文件的集合,但静态链接后,执行程序中存在自己所需obj的一份拷贝,而动态链接后,执行程序仅仅是包含对共享库的一个引用。共享库相当于一个由多个obj文件组合而成的obj文件,在链接后其所有代码被加载,不管需要的还是不需要的。

似乎可以得出一个结论:

  静态链接后的程序比动态链接的所用存储空间大,因为执行程序中包含了库中代码拷贝;

  而动态链接的程序比静态链接的所用的运行空间大,因为它将不需要的代码也加载到运行空间。

 

但是动态链接在某种意义上还节省内存,因为同一个软件模块,若是以源代码的形式重用,则会被编译到不同的可执行程序中,同时运行这些exe时这些模块的二进制码会被重复加载到内存中。如 果使用dll,则只在内存中加载一次,所有使用该dll的进程会共享此块内存(当然,像dll中的全局变量这种东西是会被每个进程复制一份的)。

 

所以dll如果比较小,且用到它的地方越多,就越比静态链接省内存。

 

使用动态库还有比使用静态库更好的一点就是,dll可以很方便的应用于C#等其他平台;如果C#想使用使用静态库LIB,也必须把LIB重新封装成dll。

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3